import utils from './index';
import config from '../config.js';

// DOM 工具方法集合
let Dom = {
    /**
     * 创建 DOM
     * @param {String} tag DOM 的标签名
     * @param {String | Array} classnames 类名，支持数组
     * @param {String} innerHTML html 内容
     * @param {Object} styles 样式对象
     * @param {Object} attribs 属性对象
     */
    createElement: (tag, classNames, innerHTML, styles, attribs) => {
        var res = false;

        if (typeof tag !== undefined) {
            res = document.createElement(tag);
        }

        if (classNames) {
            res.className = Dom.calcClassName(classNames);
        }

        if (innerHTML) {
            res.innerHTML = innerHTML;
        }

        if (styles) {
            Dom.styles(res, styles);
        }

        if (attribs) {
            utils.extend(res, attribs);
        }

        return res;
    },

    /**
     * 追加 Dom 到已经存在的 DOM 中
     * @param parent 父级 DOM
     * @param 后续的参数同 createElement
     */
    append: (parent, tag, className, innerHTML, styles, attribs) => {
        var res = Dom.createElement(tag, className, innerHTML, styles, attribs);
        parent.appendChild(res);
        return res;
    },

    /**
     * 设置属性
     */
    setAttr: (node, attribs) => {
        if (node && attribs && !utils.isObjEmpty(attribs)) {
            for (let key in attribs) {
                node.setAttribute(key, attribs[key]);
            }
        }
    },

    /**
     * 设置样式
     */
    styles: (nodes, style) => {
        if (utils.isArr(nodes)) {
            nodes.forEach(function (node) {
                Dom.style(node, style);
            });
            return nodes;
        }

        if (nodes && nodes.style) {
            Object.keys(style).forEach(function (p) {
                nodes.style[p] = style[p];
            });
            return nodes;
        }
        return false;
    },

    /**
     * 获取样式
     * @param {DOM} node
     * @param {String | undefined} properties 需要获取的样式 Key，为空则返回全部样式
     */
    getStyles: (node, properties) => {
        let styles = window.getComputedStyle(node);
        if (properties) {
            return styles[properties];
        }
        return styles
    },

    /**
     * 计算 className，支持数组和指定前缀
     */
    calcClassName: classNames => {
        let classPre = (config.classNamePre || 'itushuo') + '-';

        // 每个 Dom 的类前加 itushuo 后缀
        if (utils.isArr(classNames)) {
            // 过滤为空的 class
            classNames = classNames.filter(c => {
                return c;
            });
            classNames = classNames.join(' ' + classPre);
        }

        return classPre + classNames
    },

    /**
     * 增加 className
     */
    addClass: (node, className) => {
        node.className += ' ' + Dom.calcClassName(className);
    },

    /**
     * 阻止事件冒泡
     * @param {DOM Event} e 事件对象
     * @example
     *  `Dom.addEvent(node, 'click', e = > {
     *      return Dom.nodefault(e)
     *  })`
     * @returns false
     */
    nodefault: e => {
        e.cancelBubble = true;
        e.preventDefault();
        e.stopPropagation();
        e.stopImmediatePropagation();
        return false;
    },

    /**
     * 绑定事件
     * @param {DOM | Array} el DOM，支持多个 DOM 同时绑定
     * @param {String | Array} event 事件名称，支持多个事件同时绑定
     * @param {function} callback 事件回调函数
     * @returns {function} 用于解绑的函数
     */
    addEvent: (el, event, callback) => {
        if (!el) {
            return () => { };
        }

        var s = [];

        if (utils.isArr(event)) {
            event.forEach(e => {
                s.push(Dom.addEvent(el, e, callback));
            });
            return () => {
                s.forEach(f => {
                    f();
                });
            }
        }

        if (el && el.forEach) {
            el.forEach(e => {
                s.push(Dom.addEvent(e, event, callback));
            });
        }

        if (s.length > 0) {
            return () => {
                s.forEach(f => {
                    f();
                });
            }
        }


        if (el.addEventListener) {
            el.addEventListener(event, callback, false);
        } else {
            el.attachEvent('on' + event, callback, false);
        }

        return () => {
            if (window.removeEventListener) {
                el.removeEventListener(event, null, false);
            } else {
                el.detachEvent('on' + event);
            }
        }
    },

    /**
     * 通过 ID 或 对象来获取 DOM
     */
    get: node => {
        return typeof node === 'string' ? (document.getElementById(node) || false) : node;
    },

    /**
     * 获取 DOM 的尺寸
     * 
     * @returns {object} {w: width, h: height}
     */
    size: node => {
        return {
            w: node.clientWidth,
            h: node.clientHeight
        }
    },

    /**
     * 计算 Dom 位置，默认是相对父级的位置
     * @param {Dom} node
     * @param {boolean} isAbsolute 是否是相对位置（相对于浏览器的位置）
     * @returns {object} {x: left, y: top}
     */
    pos: (node, isAbsolute) => {
        if (isAbsolute) {
            var b = node.getBoundingClientRect();
            return {
                x: b.left + window.scrollX,
                y: b.top + window.scrollY
            };
        }

        return {
            x: node.offsetLeft,
            y: node.offsetTop
        }
    }
};

export default Dom;